import java.rmi.RemoteException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class ServerObject implements ServerObject_itf {
	
	private List<Client_itf> readers;
	private Client_itf writer;
	private int id;
	private int lock;
	public Object obj;
	
	public class Mode {
		public final static int FREE=0;		// unlocked mode
		public final static int WRITE=1;	// write mode
		public final static int READ=2;		// read mode
	}
	
	public ServerObject(Object o, int _id) throws RemoteException {
		super();
		obj = o;
		id = _id;
		lock = Mode.FREE;
		readers = new LinkedList<Client_itf>();
	}

	public synchronized Object lock_read(Client_itf client) throws RemoteException {
		if(lock==Mode.WRITE) {
			obj = writer.reduce_lock(id);
			writer = null;
		}
		if(!readers.contains(client)) {
			readers.add(client);
		}
		lock = Mode.READ;
		return obj;
	}

	public synchronized Object lock_write(Client_itf client) throws RemoteException {
		if(lock==Mode.READ){
			Iterator<Client_itf> i = readers.iterator();
			while(i.hasNext()) {
				Client_itf c = i.next();
				c.invalidate_reader(id);
				i.remove();
			}
		}
		else if(lock==Mode.WRITE){
			obj = writer.invalidate_writer(id);
		}
		lock = Mode.WRITE;
		if(!readers.contains(client)) readers.add(client);
		writer = client;
		return obj;
	}
}
